package com.ygqh.baby.controller.mobile;

import com.fasterxml.jackson.databind.util.JSONPObject;
import com.ygqh.baby.ao.*;
import com.ygqh.baby.model.PrizeItem;
import com.ygqh.baby.model.PrizeItem.Type;
import com.ygqh.baby.po.*;
import com.ygqh.baby.redis.RedisDao;
import com.ygqh.baby.service.*;
import com.ygqh.baby.utils.DateConvertUtils;
import com.ygqh.baby.utils.SessionUtil;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 抽奖活动相关
 *
 */
@Controller
@RequestMapping("/app/action")
public class YgActionController {

	protected final Logger logger = Logger.getLogger(this.getClass());

	@Autowired
	private YgUserService userService;
	@Autowired
	private RedisDao redisDao;
	@Autowired
	private YgCardCouponDetailService ygCardCouponDetailService;
	@Autowired
	private YgCouponService ygCouponService;
	@Autowired
	private YgCouponDetailService ygCouponDetailService;
	@Autowired
	private YgUserBalanceService userBalanceService;
	@Autowired
	private YgUserBalanceDetailService userBalanceDetailService;
	@Autowired
	private YgCouponUseDetailService couponUseDetailService;
	@Autowired
	private YgCardCouponService ygCardCouponService;

	@RequestMapping(value = "turnTable12", method = RequestMethod.GET)
	@ResponseBody
	public ResponseEntity turnTable12() throws ParseException {
		YgUser user = SessionUtil.getCurrentUser();
		String format = DateConvertUtils.format(new Date());
		String baseKey = "turnTable12_" + format;

		Date startDate = DateConvertUtils.parse("2018-10-30", DateConvertUtils.DATE_FORMAT);
		Date endDate = DateConvertUtils.parse("2018-11-13", DateConvertUtils.DATE_FORMAT);
		Date now = DateConvertUtils.getDateStart(new Date());
		if (now.before(startDate)) {
			return ResponseEntity.error("活动未开始", null);
		}
		if (now.after(endDate)) {
			return ResponseEntity.error("活动已结束", null);
		}
		if (redisDao.get(baseKey + "_" + user.getId()) != null) {
			return ResponseEntity.error("不要贪心,您已参与过活动,请明天再来", null);
		}
		Object[][] prizeArr;
		/**
		 * 判断用户是否是新客
		 */
		Boolean newCustom = userService.isNewCustom(user.getId());
		// 测试
		/*if (newCustom) { // 新客奖品池
			prizeArr = new Object[][] {
				{ 1, 1, "1元", "26", Type.Balance, 420, 30 },
				{ 2, 5, "5元", "10", Type.Balance, 140, 10 },
				{ 3, 9, "9元", "2", Type.Balance, 70, 5 },
				{ 4, 49, "49元", "0.5", Type.Balance, 14, 1 },
				{ 5, 1111, "1111元", "0", Type.Cash, 0, 0 },
				{ 6, 316, "21-20优惠券", "30", Type.Coupon, 10000, null },
				{ 7, 317, "200-30优惠券", "20", Type.Coupon, 10000, null },
				{ 8, 318, "400-80优惠券", "10", Type.Coupon, null, null },
				{ 9, 68, "双肩帆布包", "0.5", Type.Goods, 140, 10 },
				{ 10, 70, "粉色猫咪玩偶", "1", Type.Goods, 70, 5 }
			};
		} else { // 老客奖品池
			prizeArr = new Object[][] {
				{ 1, 1, "1元", "26.5", Type.Balance, 420, 30 },
				{ 2, 5, "5元", "10", Type.Balance, 140, 10 },
				{ 3, 9, "9元", "2", Type.Balance, 70, 5 },
				{ 4, 49, "49元", "0", Type.Balance, 14, 1 },
				{ 5, 1111, "1111元", "0", Type.Cash, 0, 0 },
				{ 6, 316, "21-20优惠券", "5", Type.Coupon, 10000, null },
				{ 7, 317, "200-30优惠券", "5", Type.Coupon, 10000, null },
				{ 8, 318, "400-80优惠券", "50", Type.Coupon, null, null },
				{ 9, 68, "双肩帆布包", "0.5", Type.Goods, 140, 10 },
				{ 10, 70, "粉色猫咪玩偶", "1", Type.Goods, 70, 5 }
			};
		}*/
		// 正式
		if (newCustom) { // 新客奖品池
			prizeArr = new Object[][] {
					{ 1, 1, "1元", "26", Type.Balance, 420, 30 },
					{ 2, 5, "5元", "10", Type.Balance, 140, 10 },
					{ 3, 9, "9元", "2", Type.Balance, 70, 5 },
					{ 4, 49, "49元", "0.5", Type.Balance, 14, 1 },
					{ 5, 1111, "1111元", "0", Type.Cash, 0, 0 },
					{ 6, 346, "21-20优惠券", "30", Type.Coupon, 10000, null },
					{ 7, 347, "200-30优惠券", "20", Type.Coupon, 10000, null },
					{ 8, 348, "400-80优惠券", "10", Type.Coupon, null, null },
					{ 9, 75, "双肩帆布包", "0.5", Type.Goods, 140, 10 },
					{ 10, 73, "粉色猫咪玩偶", "1", Type.Goods, 70, 5 }
			};
		} else { // 老客奖品池
			prizeArr = new Object[][] {
					{ 1, 1, "1元", "26.5", Type.Balance, 420, 30 },
					{ 2, 5, "5元", "10", Type.Balance, 140, 10 },
					{ 3, 9, "9元", "2", Type.Balance, 70, 5 },
					{ 4, 49, "49元", "0", Type.Balance, 14, 1 },
					{ 5, 1111, "1111元", "0", Type.Cash, 0, 0 },
					{ 6, 346, "21-20优惠券", "5", Type.Coupon, 10000, null },
					{ 7, 347, "200-30优惠券", "5", Type.Coupon, 10000, null },
					{ 8, 348, "400-80优惠券", "50", Type.Coupon, null, null },
					{ 9, 75, "双肩帆布包", "0.5", Type.Goods, 140, 10 },
					{ 10, 73, "粉色猫咪玩偶", "1", Type.Goods, 70, 5 }
			};
		}

		Integer selectId = 0;

		// 默认奖项
		Integer defaultSelectId = 7;

		/*
		 * 随机一个奖项数
		 */
		List<Double> orignalRates = new ArrayList<>();
		for (Object[] aPrizeArr : prizeArr) {
			String str = (String) aPrizeArr[3];
			orignalRates.add(Double.valueOf(str));
		}
		selectId = lottery(orignalRates);
		/*
		 * 处理抽奖结果
		 */
		boolean isDefault = false;
		if (prizeArr[selectId][5] != null) {
			// 有总数量限制，需要验证已发总数量
			String value = redisDao.get("turnTable12_giveCount_" + prizeArr[selectId][0]);
			Integer totalCount = Integer.valueOf(prizeArr[selectId][5].toString());
			// 已发数量达到峰值
			if (StringUtils.isNotBlank(value) && Integer.valueOf(value).compareTo(totalCount) >= 0) {
				isDefault = true;
			}
		}
		if (!isDefault && prizeArr[selectId][6] != null) {
			// 有每日数量限制，需要验证当日已发数量
			String value = redisDao.get(baseKey + "_giveCount_" + prizeArr[selectId][0]);
			Integer totalCount = Integer.valueOf(prizeArr[selectId][6].toString());
			// 当日已发数量达到峰值
			if (StringUtils.isNotBlank(value) && Integer.valueOf(value).compareTo(totalCount) >= 0) {
				isDefault = true;
			}
		}
		if (isDefault) {
			selectId = defaultSelectId;
		}
		Type type = (Type) prizeArr[selectId][4];
		switch (type) {
			case Balance: // 成长基金
				this.addBalance(user.getId(), new BigDecimal(prizeArr[selectId][1].toString()));
				break;
			case Coupon: // 优惠券
				Long couponId = Long.parseLong(prizeArr[selectId][1].toString());
				ygCouponDetailService.receiveCouponWithRemark(couponId, "转盘抽奖", user);
				break;
			case Goods: // 实物
				Message message = ygCardCouponDetailService.generateCardCoupon(user.getId(), Long.parseLong(prizeArr[selectId][1].toString()), null, baseKey);
				if (!Message.isSuccess(message)) {
					isDefault = true;
				}
				break;
			case Cash: // 暂无现金红包
			default:
				/*
				 *  默认赠予
				 */
				isDefault = true;
				break;
		}

		if (isDefault) {
			selectId = defaultSelectId;
			type = (Type) prizeArr[selectId][4];
			if (Type.Balance.equals(type)) {
				this.addBalance(user.getId(), new BigDecimal(prizeArr[selectId][1].toString()));
			} else if (Type.Coupon.equals(type)) {
				ygCouponDetailService.receiveCouponWithRemark(Long.parseLong(prizeArr[selectId][1].toString()), "转盘抽奖", user);
			}
		}

		redisDao.set(baseKey + "_" + user.getId(), "1", 24 * 60 * 60 * 1000);
		if (prizeArr[selectId][5] != null) {
			// 有总数量限制， 更新已领取总数量
			String key = "turnTable12_giveCount_" + prizeArr[selectId][0];
			String value = redisDao.get(key);
			if (StringUtils.isNotBlank(value)) {
				value = (Integer.valueOf(value) + 1) + "";
			} else {
				value = "1";
			}
			long expire = DateConvertUtils.addDay(endDate, 1).getTime();
			redisDao.set(key, value, expire);
			logger.info("转盘活动：【" + prizeArr[selectId][2].toString() + "】已被领取" + value + "个");
		}
		if (prizeArr[selectId][6] != null) {
			// 有每日数量限制， 更新已领取每日数量
			String key = baseKey + "_giveCount_" + prizeArr[selectId][0];
			String value = redisDao.get(key);
			if (StringUtils.isNotBlank(value)) {
				value = (Integer.valueOf(value) + 1) + "";
			} else {
				value = "1";
			}
			redisDao.set(key, value, 24 * 60 * 60 * 1000);
			logger.info("转盘活动：【" + prizeArr[selectId][2].toString() + "】今日已被领取" + value + "个");
		}
		return new ResponseEntity(CodeConstant.Success.getCode(), "0", prizeArr[selectId][0]);
	}

	public int lottery(List<Double> orignalRates) {
		if (orignalRates == null || orignalRates.isEmpty()) {
			return -1;
		}
		int size = orignalRates.size();
		// 计算总概率，这样可以保证不一定总概率是1
		double sumRate = 0d;
		for (double rate : orignalRates) {
			sumRate += rate;
		}
		// 计算每个物品在总概率的基础下的概率情况
		List<Double> sortOrignalRates = new ArrayList<>(size);
		Double tempSumRate = 0d;
		for (double rate : orignalRates) {
			tempSumRate += rate;
			sortOrignalRates.add(tempSumRate / sumRate);
		}
		// 根据区块值来获取抽取到的物品索引
		double nextDouble = Math.random();
		sortOrignalRates.add(nextDouble);
		Collections.sort(sortOrignalRates);
		return sortOrignalRates.indexOf(nextDouble);
	}

	private int addBalance(Long userId, BigDecimal money) {
		userBalanceService.backAcountPrice(userId, money);
		userBalanceDetailService.addBalanceDetail(userId, money, BalanceType.Balance, OperationType.Activity, "领取活动礼包");
		return 1;

	}

	@RequestMapping(value = "shareReward", method = RequestMethod.GET)
	@ResponseBody
	public ResponseEntity shareReward(@RequestParam(required = true) Long requestId) throws ParseException {
		Long userId = SessionUtil.getCurrentUser().getId();
		System.out.println(requestId.toString());
		YgCouponUseDetail couponUserDetail = couponUseDetailService.findCouponUseDetailByOrderId(userId, requestId.toString());
		if (couponUserDetail != null) {
			return ResponseEntity.converter(this.findCouponUseDetail(couponUserDetail));
		}

		/**
		 * 线上
		 */
		Object[][] prizeArr = new Object[][] { { 0, 45, "单次包邮卡", "37.5" }, { 1, 259, "无门槛", "42.5" }, { 2, 260, "满60元可用", "20" }, { 3, 261, "满60元可用", "20" }};

		/**
		 * 104
		 */
		/*Object[][] prizeArr = new Object[][] { { 0, 47, "单次包邮卡", "37.5" }, { 1, 250, "5元无门槛", "25" }, { 2, 251, "老用户满60减10", "37.5" }, { 3, 252, "新用户满60-20", "37.5" }};*/

		// 判断活动时间
		Date actionDate = new Date();
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		actionDate = df.parse("2018-12-31");
		Date currDate = new Date();
		if (currDate.after(actionDate)) {
			return ResponseEntity.error("此活动已经结束");
		}
		List<Double> orignalRates = new ArrayList<>();
		for (int i = 0; i < prizeArr.length; i++) {
			String str = (String) prizeArr[i][3];
			orignalRates.add(Double.valueOf(str));
		}
		Integer selectId = lottery(orignalRates);
		if (selectId > 3) {
			return ResponseEntity.error("请稍后重试", null);
		}
		YgUser user = userService.findById(SessionUtil.getCurrentUser().getId());
		Boolean newCustom = userService.isNewCustom(user.getId());

		if (user.getLevel().compareTo(10) == 0 && selectId == 0) {// 女王不可领包邮卡, 更换成商品券
			selectId = 1;
		} else if (newCustom && selectId == 2) {// 新用户不可领60-10
			selectId = 3;
		} else if (!newCustom && selectId == 3) {// 老用户不可怜60-20
			selectId = 2;
		}
		Long rewardId = Long.valueOf(prizeArr[selectId][1].toString());
		String remark = "订单分享赠券：requestId-->" + requestId;
		YgCouponUseDetail ygCouponUseDetail = new YgCouponUseDetail();
		Map<String, Object> data = new HashMap<>();
		if (selectId == 0) { // selectId为0，保存卡券
			List<YgCardCoupon> cardCouponList = ygCardCouponService.findCardsByMonth(CardType.ShareReward, CardMode.Card, null);
			if (CollectionUtils.isEmpty(cardCouponList)) {
				return ResponseEntity.error("请稍后重试", null);
			}
			YgCardCoupon cardCoupon = cardCouponList.get(0);
			ygCardCouponDetailService.saveCardCouponDetail(user.getId(), cardCoupon, null, requestId.toString());
			ygCouponUseDetail.setUseType(UseType.Card);
			ygCouponUseDetail.setRemark(cardCoupon.getTitle());
			data.put("price", 10);
			data.put("type", "card");
		} else {
			Message receiveCouponMsg = ygCouponDetailService.receiveCouponWithRemark(rewardId, remark, user);
			if (!receiveCouponMsg.getType().equals(Message.Type.success)) {
				return ResponseEntity.converter(receiveCouponMsg);
			}
			ygCouponUseDetail.setUseType(UseType.Coupon);
			YgCouponDetail couponDetail = (YgCouponDetail) receiveCouponMsg.getExtra();
			YgCoupon coupon = couponDetail.getCoupon();
			ygCouponUseDetail.setRemark(coupon .getCouponTitle());
			data.put("price", coupon.getFaceValue());
			data.put("type", "coupon");
		}
		Date date = new Date();
		ygCouponUseDetail.setOrderId(requestId);
		ygCouponUseDetail.setCreateTime(date);
		ygCouponUseDetail.setRelationId(rewardId);
		String string = requestId.toString();
		ygCouponUseDetail.setShareUserId(Long.valueOf(string.substring(0, string.length() - 13)));
		ygCouponUseDetail.setUserId(user.getId());
		couponUseDetailService.save(ygCouponUseDetail);
		data.put("title", ygCouponUseDetail.getRemark());
		data.put("createTime", date);
		return ResponseEntity.success(data);
	}

	private Message findCouponUseDetail(YgCouponUseDetail couponUserDetail) {
		Map<String, Object> data = new HashMap<>();
		if (couponUserDetail.getUseType().equals(UseType.Card)) {
			List<YgCardCouponDetail> list = ygCardCouponDetailService.findByRemark(couponUserDetail.getUserId(), couponUserDetail.getOrderId().toString(), DataStatus.Valid);
			data.put("price", 10);
			data.put("type", "card");
			data.put("useStatus", list.get(0).getUseStatus());
		} else if (couponUserDetail.getUseType().equals(UseType.Coupon)) {
			YgCoupon coupon = ygCouponService.findById(couponUserDetail.getRelationId());
			List<YgCouponDetail> list = ygCouponDetailService.findByCouponBatchId(coupon.getId(), couponUserDetail.getUserId());
			for (YgCouponDetail ygCouponDetail : list) {
				String remark = ygCouponDetail.getRemark();
				if (StringUtils.isNotBlank(remark) && remark.equals("订单分享赠券：requestId-->" + couponUserDetail.getOrderId())) {
					data.put("price", coupon.getFaceValue());
					data.put("type", "coupon");
					data.put("useStatus", ygCouponDetail.getUseStatus().equals(CouponStatus.Used) ? "Used" : "UnUsed");
					break;
				}
			}
		}
		data.put("title", couponUserDetail.getRemark());
		data.put("createTime", couponUserDetail.getCreateTime());
		return Message.success(data);
	}


}
